#include "HDRManager.hpp"
#include "HDRImageObject.hpp"
#include <iostream>

using namespace std;

//set static variable to null
HDRManager* HDRManager::m_pInstance = 0;

bool HDRManager::createInstance()
{
	bool bSuccess = false;

	if(!m_pInstance)
	{
		m_pInstance = new HDRManager();

		if(m_pInstance)
			bSuccess = true;
	}

	return bSuccess;
}

void HDRManager::destroyInstance()
{
	delete m_pInstance;
	m_pInstance = NULL;
}

HDRManager* HDRManager::getInstance()
{
	return m_pInstance;
}

HDRManager::~HDRManager()
{
	typedef std::map<std::string, HDRImageObject*>::iterator hdrMapIt;

	hdrMapIt mapCurrent = m_hdrMap.begin();
	hdrMapIt mapEnd     = m_hdrMap.end();

	for(mapCurrent; mapCurrent != mapEnd; ++mapCurrent)
	{
		if(mapCurrent->second)
		{
			cout << "   WARNING!: unreleased memory object:    HDRImageObject" << endl;
			cout << "                   memory object name:    " << mapCurrent->first << endl;
			cout << "                  memory object count:    " << mapCurrent->second->GetCounter() << endl;
		}
	}
}

bool HDRManager::isAlreadyLoaded(string fileName)
{
	if(m_hdrMap.find(fileName) == m_hdrMap.end())
		return false;

	return true;
}

bool HDRManager::loadHDR(string fileName)
{
	bool bSuccess = false;

	if(!isAlreadyLoaded(fileName))
	{
		HDRImageObject* pNewHDR = new HDRImageObject(fileName);

		if(pNewHDR)
		{
			m_hdrMap.insert(make_pair(fileName, pNewHDR));
			pNewHDR->IncreaseCounter();

			bSuccess = true;
		}
	}
	else
	{
		HDRImageObject* pHDR = m_hdrMap.find(fileName)->second;
		pHDR->IncreaseCounter();

		bSuccess = true;
	}

	return bSuccess;
}

bool HDRManager::unloadHDR(string fileName)
{
	typedef map<string, HDRImageObject*>::const_iterator cHDRMapIt;
	
	bool bSuccess = false;
	cHDRMapIt iterator = m_hdrMap.find(fileName);

	if(iterator == m_hdrMap.end())
		return bSuccess;

	HDRImageObject* pHDR = iterator->second;

	if(pHDR->GetCounter() > 1)
		pHDR->DecreaseCounter();
	else
	{
		delete pHDR;
		m_hdrMap[fileName] = NULL;
		m_hdrMap.erase(iterator);
	}

	bSuccess = true;
	return bSuccess;
}

const HDRImageObject* HDRManager::getHDR(string fileName)
{
	if(m_hdrMap.find(fileName) == m_hdrMap.end())
		return NULL;
	else
		return m_hdrMap[fileName];
}

const string& HDRManager::getObjectName(const HDRImageObject* pHDR)
{
	typedef map<string, HDRImageObject*>::iterator hdrMapIt;

	hdrMapIt current = m_hdrMap.begin();
	hdrMapIt end     = m_hdrMap.end();

	for(current; current != end; ++current)
	{
		HDRImageObject* pHDRTemp = current->second;
		if(pHDRTemp == const_cast<HDRImageObject*>(pHDR))
			return current->first;
	}

	throw HDRM_EX_NAME_NOT_FOUND;
}

//EOF
